package com.symaster.common.swing.element;

import com.symaster.common.swing.layout.CenterList;
import com.symaster.common.swing.layout.ExtensionLayout;

import javax.swing.*;
import java.awt.*;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseListener;

/**
 * @author yinmiao
 * @date 2022-03-24 15:48
 */
public class CardListPanel extends JPanel {

    public enum ExtensionDirection {
        HORIZONTAL(ExtensionLayout.ExtensionDirection.HORIZONTAL),
        VERTICAL(ExtensionLayout.ExtensionDirection.VERTICAL);

        private final ExtensionLayout.ExtensionDirection extensionDirection;

        ExtensionDirection(ExtensionLayout.ExtensionDirection extensionDirection) {
            this.extensionDirection = extensionDirection;
        }

        public ExtensionLayout.ExtensionDirection getExtensionDirection() {
            return extensionDirection;
        }
    }

    public static final int LEFT = 0;
    public static final int CENTER = 1;
    public static final int RIGHT = 2;
    public static final int LEADING = 3;
    public static final int TRAILING = 4;

    private Integer itemWidth;
    private Integer itemHeight;
    private final JComponent centerList;
    private final JScrollPane scrollPane;

    public CardListPanel(Integer itemWidth, Integer itemHeight, int hGap, int vGap, int align, ExtensionDirection extensionDirection) {
        this.itemWidth = itemWidth;
        this.itemHeight = itemHeight;

        this.scrollPane = createScrollPane();
        super.setLayout(new BorderLayout());
        super.add(this.scrollPane, BorderLayout.CENTER);

        this.centerList = createCenterList(hGap, vGap, align, extensionDirection);
        this.scrollPane.setViewportView(this.centerList);
    }

    public CardListPanel(Integer itemWidth, Integer itemHeight, int hGap, int vGap, int align) {
        this(itemWidth, itemHeight, hGap, vGap, CENTER, ExtensionDirection.VERTICAL);
    }

    public CardListPanel(Integer itemWidth, Integer itemHeight, int hGap, int vGap) {
        this(itemWidth, itemHeight, hGap, vGap, CENTER);
    }

    public CardListPanel(int hGap, int vGap, String name) {
        this(null, null, hGap, vGap, CENTER);
    }

    public CardListPanel(int hGap, int vGap) {
        this(null, null, hGap, vGap, CENTER);
    }

    public CardListPanel() {
        this(5, 5);
    }

    private JComponent createCenterList(int hGap, int vGap, int align, ExtensionDirection extensionDirection) {
        ExtensionLayout extensionLayout = new ExtensionLayout(
                itemWidth == null ? -1 : itemWidth,
                itemHeight == null ? -1 : itemHeight,
                hGap, vGap, align,
                extensionDirection.getExtensionDirection()
        );
        CenterList centerList = new CenterList();
        centerList.setLayout(extensionLayout);
        if (getBackground() != null) {
            centerList.setBackground(getBackground());
        }
        return centerList;
    }

    private JScrollPane createScrollPane() {
        JScrollPane scrollPane = new JScrollPane();
        if (getBackground() != null) {
            scrollPane.setBackground(getBackground());
        }
        scrollPane.getVerticalScrollBar().setUnitIncrement(20);
        scrollPane.getHorizontalScrollBar().setUnitIncrement(20);
        scrollPane.setBorder(null);
        return scrollPane;
    }

    public void addHAdjustmentListener(AdjustmentListener l) {
        this.scrollPane.getHorizontalScrollBar().addAdjustmentListener(l);
    }

    public void addVAdjustmentListener(AdjustmentListener l) {
        this.scrollPane.getVerticalScrollBar().addAdjustmentListener(l);
    }

    public void listAddMouseListener(MouseListener l) {
        centerList.addMouseListener(l);
    }

    public void setItemSize(Dimension dimension) {
        if (dimension == null) {
            itemWidth = null;
            itemHeight = null;
        } else {
            itemWidth = dimension.width;
            itemHeight = dimension.height;
        }
    }

    public void setItemHeight(Integer itemHeight) {
        this.itemHeight = itemHeight;
    }

    public void listRemove(int index) {
        centerList.remove(index);
    }

    public void listRemove(Component com) {
        centerList.remove(com);
    }

    public void listRemoveAll() {
        centerList.removeAll();
        centerList.updateUI();
    }

    public int listComponentCount() {
        return centerList.getComponentCount();
    }

    public Component[] listComponents() {
        return centerList.getComponents();
    }

    public void listAdd(Component com) {
        centerList.add(com);
    }

    public void listAddAll(Iterable<Component> components) {
        components.forEach(this::listAdd);
    }

    public void listAdd(Component comp, Object constraints, int index) {
        centerList.add(comp, constraints, index);
    }

    public void listAdd(Component comp, int index) {
        centerList.add(comp, index);
    }

    public static void main(String[] args) {
        CardListPanel cardListPanel = new CardListPanel(-1, 20, 5, 5, CENTER, ExtensionDirection.HORIZONTAL);
        for (int i = 0; i < 30; i++) {
            cardListPanel.listAdd(new JButton("Test-" + i));
        }

        JFrame jFrame = new JFrame();
        jFrame.setPreferredSize(new Dimension(900, 100));
        jFrame.setContentPane(cardListPanel);
        jFrame.pack();
        jFrame.setVisible(true);
    }

    @Override
    @Deprecated
    public int getComponentCount() {
        return super.getComponentCount();
    }

    @Override
    @Deprecated
    public Component getComponent(int n) {
        return super.getComponent(n);
    }

    @Override
    @Deprecated
    public Component[] getComponents() {
        return super.getComponents();
    }

    @Override
    @Deprecated
    public int getComponentZOrder(Component comp) {
        return super.getComponentZOrder(comp);
    }

    @Override
    @Deprecated
    public Component getComponentAt(int x, int y) {
        return super.getComponentAt(x, y);
    }

    @Override
    @Deprecated
    public Component getComponentAt(Point p) {
        return super.getComponentAt(p);
    }

    @Override
    @Deprecated
    public Component add(Component comp, int index) {
        return super.add(comp, index);
    }

    @Override
    @Deprecated
    public void add(Component comp, Object constraints) {
        super.add(comp, constraints);
    }

    @Override
    @Deprecated
    public void add(Component comp, Object constraints, int index) {
        super.add(comp, constraints, index);
    }

    @Override
    @Deprecated
    public Component add(Component comp) {
        return super.add(comp);
    }

    @Override
    @Deprecated
    public void removeAll() {
        super.removeAll();
    }

    @Override
    @Deprecated
    public void remove(Component comp) {
        super.remove(comp);
    }

    @Override
    @Deprecated
    public void remove(int index) {
        super.remove(index);
    }

    @Override
    public void setBackground(Color bg) {
        super.setBackground(bg);
        if (centerList != null) {
            centerList.setBackground(getBackground());
        }
    }
}
